"""
用户认证相关的数据模型

这个文件定义了用户相关的数据库模型，包括用户资料扩展等。
"""
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.core.validators import RegexValidator
import uuid


class User(AbstractUser):
    """
    自定义用户模型
    
    扩展Django默认用户模型，添加额外字段如手机号、头像等。
    继承AbstractUser保留了Django用户系统的所有功能。
    """
    
    # 手机号验证器
    phone_validator = RegexValidator(
        regex=r'^1[3-9]\d{9}$',
        message='请输入有效的手机号码'
    )
    
    # 用户唯一标识
    id = models.UUIDField(
        primary_key=True, 
        default=uuid.uuid4, 
        editable=False,
        verbose_name='用户ID'
    )
    
    # 邮箱字段（必填且唯一）
    email = models.EmailField(
        unique=True,
        verbose_name='邮箱地址',
        help_text='用户的邮箱地址，用于登录和找回密码'
    )
    
    # 手机号字段
    phone = models.CharField(
        max_length=11,
        unique=True,
        validators=[phone_validator],
        verbose_name='手机号码',
        help_text='用户的手机号码，用于登录和接收通知'
    )
    
    # 用户头像
    avatar = models.ImageField(
        upload_to='avatars/',
        blank=True,
        null=True,
        verbose_name='头像',
        help_text='用户头像图片'
    )
    
    # 用户昵称
    nickname = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='昵称',
        help_text='用户显示昵称'
    )
    
    # 用户简介
    bio = models.TextField(
        max_length=500,
        blank=True,
        verbose_name='个人简介',
        help_text='用户个人简介'
    )
    
    # 是否验证邮箱
    email_verified = models.BooleanField(
        default=False,
        verbose_name='邮箱已验证',
        help_text='用户是否已验证邮箱'
    )
    
    # 是否验证手机
    phone_verified = models.BooleanField(
        default=False,
        verbose_name='手机已验证',
        help_text='用户是否已验证手机号'
    )
    
    # 最后登录IP
    last_login_ip = models.GenericIPAddressField(
        blank=True,
        null=True,
        verbose_name='最后登录IP',
        help_text='用户最后一次登录的IP地址'
    )
    
    # 创建时间
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间'
    )
    
    # 更新时间
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='更新时间'
    )
    
    class Meta:
        verbose_name = '用户'
        verbose_name_plural = '用户'
        db_table = 'accounts_user'  # 修改表名，避免与auth_user冲突
        ordering = ['-created_at']
    
    def __str__(self):
        """字符串表示"""
        return f"{self.username} ({self.email})"
    
    def get_display_name(self):
        """获取显示名称"""
        return self.nickname or self.username
    
    def get_full_name(self):
        """获取全名"""
        return f"{self.first_name} {self.last_name}".strip() or self.username


class UserProfile(models.Model):
    """
    用户资料扩展模型
    
    存储用户的额外信息，如偏好设置、统计数据等。
    与User模型一对一关联。
    """
    
    # 关联用户（一对一）
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='profile',
        verbose_name='用户'
    )
    
    # 用户偏好设置
    theme = models.CharField(
        max_length=20,
        choices=[
            ('light', '浅色主题'),
            ('dark', '深色主题'),
            ('auto', '自动切换'),
        ],
        default='light',
        verbose_name='主题偏好'
    )
    
    # 语言偏好
    language = models.CharField(
        max_length=10,
        choices=[
            ('zh-cn', '简体中文'),
            ('en', 'English'),
        ],
        default='zh-cn',
        verbose_name='语言偏好'
    )
    
    # 时区设置
    timezone = models.CharField(
        max_length=50,
        default='Asia/Shanghai',
        verbose_name='时区设置'
    )
    
    # 邮件通知设置
    email_notifications = models.BooleanField(
        default=True,
        verbose_name='邮件通知',
        help_text='是否接收邮件通知'
    )
    
    # 短信通知设置
    sms_notifications = models.BooleanField(
        default=False,
        verbose_name='短信通知',
        help_text='是否接收短信通知'
    )
    
    # 登录次数统计
    login_count = models.PositiveIntegerField(
        default=0,
        verbose_name='登录次数'
    )
    
    # 创建时间
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间'
    )
    
    # 更新时间
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='更新时间'
    )
    
    class Meta:
        verbose_name = '用户资料'
        verbose_name_plural = '用户资料'
        db_table = 'user_profile'
    
    def __str__(self):
        return f"{self.user.username}的资料"


class LoginLog(models.Model):
    """
    用户登录日志模型
    
    记录用户的登录历史，包括登录时间、IP地址、设备信息等。
    用于安全审计和用户行为分析。
    """
    
    # 关联用户
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='login_logs',
        verbose_name='用户'
    )
    
    # 登录IP地址
    ip_address = models.GenericIPAddressField(
        verbose_name='IP地址'
    )
    
    # 用户代理（浏览器信息）
    user_agent = models.TextField(
        verbose_name='用户代理',
        help_text='浏览器和设备信息'
    )
    
    # 登录状态
    status = models.CharField(
        max_length=20,
        choices=[
            ('success', '成功'),
            ('failed', '失败'),
            ('blocked', '被阻止'),
        ],
        default='success',
        verbose_name='登录状态'
    )
    
    # 失败原因（如果登录失败）
    failure_reason = models.CharField(
        max_length=100,
        blank=True,
        verbose_name='失败原因'
    )
    
    # 登录时间
    login_time = models.DateTimeField(
        auto_now_add=True,
        verbose_name='登录时间'
    )
    
    # 登出时间
    logout_time = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name='登出时间'
    )
    
    # 会话持续时间（秒）
    session_duration = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name='会话时长（秒）'
    )
    
    class Meta:
        verbose_name = '登录日志'
        verbose_name_plural = '登录日志'
        db_table = 'login_log'
        ordering = ['-login_time']
        indexes = [
            models.Index(fields=['user', '-login_time']),
            models.Index(fields=['ip_address']),
            models.Index(fields=['status']),
        ]
    
    def __str__(self):
        return f"{self.user.username} - {self.login_time} - {self.status}"
    
    def calculate_duration(self):
        """计算会话持续时间"""
        if self.logout_time:
            duration = (self.logout_time - self.login_time).total_seconds()
            self.session_duration = int(duration)
            self.save(update_fields=['session_duration'])
            return duration
        return None